from core.layer import Layer

__author__ = 'Douglas'


class NeuralNetwork:
    def __init__(self):
        self.__layers = []
        """:type : list[Layer]"""

        self.__input_layer = None
        """:type : Layer"""

    def add_layer(self, neuron_count, input_function, activation_function):
        """
        :type neuron_count: int
        :type input_function: TransferFunction
        :type activation_function:
        """
        self._add_layer(Layer(neuron_count, input_function, activation_function))

    def _add_layer(self, new_layer):
        """
        :type new_layer: Layer
        """

        if len(self.__layers) == 0:
            self.__input_layer = new_layer
        else:
            new_layer.previous = self.__layers[-1]

        self.__layers.append(new_layer)

    def remove_layer(self, index):
        del self.__layers[index]

        if len(self.__layers) == 0:
            self.__input_layer = None
        else:
            for i in range(1, len(self.__layers)):
                self.__layers[i + 1].previous = self.__layers[i]


    def remove_all_layers(self):
        self.__layers.clear()
        self.__input_layer = None

    def compute(self, pattern):
        """
        :type pattern: list[float]
        """

        # sets the input layer with the pattern
        for neuron, p in zip(self.__input_layer.neurons, pattern):
            neuron.input = p

        for layer in self.__layers:
            layer.compute_neurons(pattern)

        return [neuron.output for neuron in self.__layers[-1].neurons]

    def randomize_weights(self):
        for layer in self.__layers:
            layer.randomize_neurons_weights()